﻿using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
using System.Collections;
using System.Web;

namespace Ehai.Web.Framework.Rules
{
    class MsgReplaceRuleHandle:IMsgRuleHandle
    {
        #region IMsgRuleHandle 成员

        public const string Name = "msgreplace";

        private int _execStatus = 0;
        public int ExecStatus
        {
            get { return _execStatus; }
        }

        private static int x = 0;
        private static int y = 1;
        private static Hashtable mytable = new Hashtable();
        private static Hashtable hash = new Hashtable();

        /// <summary>
        /// 替换指定文件类型中的指定字符串
        /// </summary>
        /// <param name="p">
        /// 传入数组<br />
        /// 0:(必选)处理类型,msgreplace<br />
        /// 1:(必选)要替换文件的相对路径<br />
        /// 2:(必选)要替换的文件类型<br />
        /// 3:(必选)存储替换内容的xml文件<br />
        /// </param>
        /// <param name="ci">环境变量</param>
        ///<example>
        /// string[] p = {"replace", "D:\ehai2009实践\8.11\ReplaceXMLProject\Test", ".htm", "a.xml"}; 把要替换的内容用写在 /*@*/"V7 "/*@*/里,例如要对 哈哈哈 加密, 则 /*@*/"V7哈哈哈"/*@*/ 
        /// </example>
        /// <returns>返回替换信息</returns>
        public string[][] Execute(string[] p, ContextInfo ci)
        {
            string path=p[1];
            string ext=p[2];
            string outFile = p[3];
            string da = "";

            // 判断要查找的目录是否存在
            if (Directory.Exists(@path) == false)
            {
                return new string[1][] { new string[] { "该目录不存在" } };
            }
            else
            {
                // 将用户输入的文件类型分割
                string[] arrayDom = ext.Split(',');

                #region 循环处理各种文件类型

                for (int i = 0; i < arrayDom.Length; i++)
                {
                    // 创建一个路径对象
                    DirectoryInfo dir = new DirectoryInfo(@path);

                    // 对每个文件进行操作
                    FileInfo[] file = dir.GetFiles("*" + arrayDom[i]);

                    if (file.Length == 0)
                    {
                        return new string[1][] { new string[] { "不存在此类型的文件" } };
                    }
                    for (int j = 0; j < file.Length; j++)
                    {
                        // 创建一个读取该文件的对象
                        StreamReader r = new StreamReader(@path + "\\" + file[j]);

                        // 获取文件中的所有内容并将其存在textAll中
                        string textAll = r.ReadToEnd();
                        r.Close();

                        // 正则表达式的参数
                        System.Text.RegularExpressions.RegexOptions options =
                            (System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace
                            | System.Text.RegularExpressions.RegexOptions.Multiline
                            | System.Text.RegularExpressions.RegexOptions.IgnoreCase
                            | System.Text.RegularExpressions.RegexOptions.Singleline);

                        // 构造个正则表达式的对象
                        Regex rx = new Regex("(?:/\\*\\@\\*/\\s*\\\").*?(?:\\\"\\s*/\\*\\@\\*/)", options);
                        textAll = rx.Replace(textAll, new MatchEvaluator(replaceCC));

                        // 创建一个写文件的对象
                        StreamWriter w = new StreamWriter(@path + "\\" + file[j]);

                        // 将内容写入到文件中去
                        w.WriteLine(textAll);
                        w.Close();
                    }
                }

                #endregion

                if (x == 0)
                {
                    da += "没有找到匹配项\n";
                }
                else
                {
                    da += "共找到" + x + "个匹配项,并且替代成功!";
                    x = 0;
                }

                #region 打开xml文档并且在里面创建节点

                XmlDocument document = new XmlDocument();
                document.Load(@path + "\\" + outFile);

                XmlElement root = document.DocumentElement;
                root.RemoveAll();
                foreach (DictionaryEntry dic in mytable)
                {
                    XmlElement newcontent = document.CreateElement("content");
                    XmlAttribute att0 = document.CreateAttribute("id" + y);
                    XmlAttribute att1 = document.CreateAttribute("ct" + y);
                    att0.Value = (string)dic.Value;
                    att1.Value = (string)dic.Key;
                    newcontent.SetAttributeNode(att0);
                    newcontent.SetAttributeNode(att1);
                    root.InsertAfter(newcontent, root.LastChild);
                    y++;
                }
                y = 1;

                // 保存文件
                document.Save(@path + "\\" + outFile);
                mytable.Clear();
                //return new string[1][] { new string[] { "success" } };

                #endregion

                return new string[1][] { new string[] { da } };
            }
        }

        public string GetHelpInfo()
        {
            return "替换指定字符串";
        }

        public string GetHelpDetail()
        {
            return "替换指定路径及类型的文件中的指定字符串:<br />" +
                   "例1: {replace, D:\\ehai2009实践\\8.11\\ReplaceXMLProject\\Test, .htm, a.xml};" +
                   "返回:替换信息";
        }

        public string[] GetParametersInfo()
        {
            string[] t = new string[4];
            t[0] = "(必选)处理类型,replace";
            t[1] = "(必选)要替换文件的相对路径";
            t[2] = "(必选)要替换的文件类型";
            t[3] = "(必选)存储替换内容的xml文件";
            return t;
        }

        #endregion

        #region 字符串替代函数

        private static string replaceCC(Match m)
        {
            int store = mytable.Count + 1;

            // 正则表达式的参数
            System.Text.RegularExpressions.RegexOptions options =
               (System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace
               | System.Text.RegularExpressions.RegexOptions.Multiline
               | System.Text.RegularExpressions.RegexOptions.IgnoreCase
               | System.Text.RegularExpressions.RegexOptions.Singleline);

            Regex r = new Regex("(?<=/\\*\\@\\*/\\s*\\\").*?(?=\\\"\\s*/\\*\\@\\*/)", options);
            Match n = r.Match(m.Value);
            string a = System.Text.RegularExpressions.Regex.Replace(n.Value, "(?:\\\\\\r\\n\\s+)", "");
            if (mytable.ContainsKey(a))
            {
                x++;
                return "/*@*/\"" + mytable[a] + "\"/*@*/";
            }
            else
            {
                mytable.Add(a, HttpUtility.UrlDecode("%5" + (2 * store).ToString() + "7%16"));
            }
            x++;
            return "/*@*/\"" + HttpUtility.UrlDecode("%5" + (2 * store).ToString() + "7%16") + "\"/*@*/";
        }

        #endregion
    }
}
